home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-13
/
mg2a_src.zip
/
FILEIO.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-02-16
|
11KB
|
483 lines
/*
* Name: Mg 2a
* MSDOS file I/O (TurboC 1.5)
*/
#include "def.h"
#include <stdio.h>
#ifdef MSC
#include <dos.h>
#endif /* MSC */
#ifndef F_OK
#define F_OK 0
#define X_OK 1
#define W_OK 2
#define R_OK 4
#endif
#ifndef NO_DIR
extern char *wdir;
#endif
static FILE *ffp;
/*
* Open a file for reading.
*/
ffropen(fn)
char *fn;
{
if ((ffp=fopen(fn, "rb")) == NULL)
return (FIOFNF);
return (FIOSUC);
}
/*
* Open a file for writing.
* Return TRUE if all is well, and
* FALSE on error (cannot create).
*/
ffwopen(fn)
char *fn;
{
if ((ffp=fopen(fn, "wb")) == NULL) {
ewprintf("Cannot open file for writing");
return (FIOERR);
}
return (FIOSUC);
}
/*
* Close a file.
* Should look at the status.
*/
ffclose()
{
(VOID) fclose(ffp);
return (FIOSUC);
}
/*
* Write a line to the already
* opened file. The "buf" points to the
* buffer, and the "nbuf" is its length, less
* the free newline. Return the status.
* Check only at the newline.
*/
ffputline(buf, nbuf)
register char buf[];
{
register int i;
for (i=0; i<nbuf; ++i)
putc(buf[i]&0xFF, ffp);
putc('\r', ffp); /* MSDOS wants \r\n line seperators */
putc('\n', ffp);
if (ferror(ffp) != FALSE) {
ewprintf("Write I/O error");
return (FIOERR);
}
return (FIOSUC);
}
/*
* Write a buffer to the already
* opened file. bp points to the
* buffer. Return the status.
* Check only at the newline and
* end of buffer.
*/
ffputbuf(bp)
BUFFER *bp;
{
register char *cp;
register char *cpend;
register LINE *lp;
register LINE *lpend;
lpend = bp->b_linep;
lp = lforw(lpend);
do {
cp = <ext(lp)[0]; /* begining of line */
cpend = &cp[llength(lp)]; /* end of line */
while(cp != cpend) {
putc(*cp, ffp);
cp++; /* putc may evalualte arguments more than once */
}
lp = lforw(lp);
if(lp == lpend) break; /* no implied newline on last line */
putc('\r', ffp); /* MSDOS wants \r\n line seperators */
putc('\n', ffp);
} while(!ferror(ffp));
if(ferror(ffp)) {
ewprintf("Write I/O error");
return FIOERR;
}
return FIOSUC;
}
/*
* Read a line from a file, and store the bytes
* in the supplied buffer. Stop on end of file or end of
* line. Don't get upset by files that don't have an end of
* line on the last line; this seem to be common on CP/M-86 and
* MS-DOS. Delete any CR followed by a NL: This is the normal
* format for MS_DOS files, but also occurs when files are transferred
* from VMS or MS-DOS to Unix.
*/
ffgetline(buf, nbuf, nbytes)
register char buf[];
register int *nbytes;
{
register int c;
register int i;
i = 0;
for (;;) {
c = getc(ffp);
rescan:
if (c == '\r') { /* Delete any non-stray */
c = getc(ffp); /* carriage returns. */
if (c != '\n') {
buf[i++] = '\r';
if (i >= nbuf) return FIOLONG;
goto rescan;
}
}
if (c==EOF || c=='\n') /* End of line. */
break;
buf[i++] = c;
if (i >= nbuf) return FIOLONG;
}
if (c == EOF && ferror(ffp) != FALSE) {
ewprintf("File read error");
return FIOERR;
}
*nbytes = i;
return c==EOF ? FIOEOF : FIOSUC;
}
#ifndef NO_BACKUP
/*
* Rename the file "fname" into a backup copy.
* On Unix the backup has the same name as the
* original file, with a "~" on the end - unfortunately
* this does not map well to MS-DOS - the old .bak convention
* is used.
*/
fbackupfile(fname)
char *fname;
{
register char *nname, *ptr;
char *strchr();
if ((nname=malloc(strlen(fname)+3+1)) == NULL)
return (ABORT);
(void) strcpy(nname, fname);
if ((ptr = strchr(nname, '.')) != 0)
strcpy(ptr, ".bak");
else
strcat(ptr, ".bak");
if (strcmp(fname, nname) == 0) {
free(nname);
return FALSE;
}
(void) unlink(nname); /* Ignore errors. */
(void) rename(fname, nname);
free(nname);
return (TRUE);
}
#endif
/*
* The string "fn" is a file name.
* convert all filenames to lower case, and convert all '\\' characters
* to forward slashes. This is simply my preference, uppercase and
* back slashes are also viable.
*/
/*ARGSUSED*/
adjustmsdos(fn)
register char *fn;
{
register char c;
while ((c = *fn) != '\0') {
if (ISUPPER(c))
*fn = TOLOWER(c);
if (c=='/')
*fn = '\\';
++fn;
}
}
#ifndef NO_STARTUP
#define STARTUPNAME ".mg"
/*
* find the users startup file, and return it's name. Check for
* if MGSTARTUP is defined, then use that. Otherwise, look
* for .mg in the current directory, then in the root directory.
*/
char *
startupfile()
{
register char *file;
static char temp[NFILEN];
char *getenv();
if ((file = getenv("MGSTARTUP")) != NULL )
{
if (access(file, F_OK) == 0)
return file;
return NULL;
}
if (access (STARTUPNAME, F_OK) == 0)
return STARTUPNAME;
strcpy(temp, "/");
strcat(temp, STARTUPNAME);
if (access (temp, F_OK) == 0)
return temp;
return NULL;
}
#endif
/*******************************************************************/
/* new stuff between release 1a and 2a */
/*******************************************************************/
/* convert all filenames to a canonical format, which in the case of
* MSDOS is X:/currentdir/filename. Note that each drive letter has
* it's OWN current directory, so if the user specifies a drive letter,
* we use that drive's current directory, not it's root.
*/
/* MSC doesn't have getdrive and getcurdir routines; simulate them.
* They are both pretty gross. Blame Microsoft */
#ifdef MSC
unsigned getdisk()
{
unsigned currentdrive;
_dos_getdrive(¤tdrive);
return currentdrive-1;
}
void getcurdir(unsigned drivenumber, char *buf)
{
unsigned currentdrive = getdisk()+1;
unsigned number_of_drives; /* unused */
static char bufr[NFILEN];
_dos_setdrive(drivenumber, &number_of_drives);
getcwd(&bufr[0], NFILEN-1);
_dos_setdrive(currentdrive, &number_of_drives);
strcpy(buf, &bufr[3]);
}
#endif
char *adjustname(fn)
register char *fn;
{
register char *cp;
static char fnb[NFILEN];
struct passwd *pwent;
cp = fnb;
/* handle A:foo\bar */
if (fn[0] && fn[1] == ':') {
*cp++ = *fn++;
*cp++ = *fn++;
*cp = '\0';
adjustmsdos(fnb); /* force case to lower */
if (*fn != '/' && *fn != '\\') {
*cp++ = '\\';
getcurdir(fnb[0]-'a'+1, cp);
cp = fnb + strlen(fnb);
}
else
*cp++ = *fn++;
}
/* handle \foo\bar */
else if (*fn == '/' || *fn == '\\') {
*cp++ = (char) (getdisk() + 'a');
*cp++ = ':';
*cp++ = *fn++;
}
else {
strcpy(fnb, wdir);
cp = fnb + strlen(fnb);
}
if(cp != fnb && cp[-1] != '/' && cp[-1] != '\\') *cp++ = '\\';
/* at this point, we should have a drive, and at least a single */
/* slash. Now copy over the rest of the filename, while handling */
/* certain pathalogical cases */
/* convert "//" to "/", "/./" to "/", and "/x/../" to "/" */
while(*fn) {
switch(*fn) {
case '.':
switch(fn[1]) {
case '\0':
*--cp = '\0';
adjustmsdos(fnb);
return fnb;
case '/':
case '\\':
fn += 2;
continue;
case '.':
if(fn[2]=='/' || fn[2]=='\\' || fn[2] == '\0') {
--cp;
while(cp > fnb && *--cp != '/' && *cp != '\\')
;
if (cp==fnb) cp += 2;
++cp;
if(fn[2]=='\0') {
*--cp = '\0';
adjustmsdos(fnb);
return fnb;
}
fn += 3;
continue;
}
break;
default:
break;
}
break;
case '/':
case '\\':
fn++;
continue;
default:
break;
}
while(*fn && (*cp++ = *fn++) != '/' && fn[-1] != '\\')
;
}
if (cp != fnb + 3 && cp[-1]=='\\') --cp;
*cp = '\0';
adjustmsdos(fnb);
return fnb;
}
#ifndef NO_DIRED
#include "kbd.h"
#define DIRFILE "_dirlist_.$$$"
BUFFER *dired_(dirname)
char *dirname;
{
register BUFFER *bp;
char line[256];
BUFFER *findbuffer();
char *strncpy();
int i;
if((dirname = adjustname(dirname)) == NULL) {
ewprintf("Bad directory name");
return NULL;
}
if((bp = findbuffer(dirname)) == NULL) {
ewprintf("Could not create buffer");
return NULL;
}
if(bclear(bp) != TRUE) return FALSE;
(VOID) strcpy(line, "dir ");
(VOID) strcat(line, dirname);
(VOID) strcat(line, " > ");
(VOID) strcat(line, DIRFILE);
system(line);
if (ffropen(DIRFILE) != FIOSUC) {
ewprintf("Can't open temporary dir file");
return NULL;
}
line[0] = line[1] = ' ';
if (ffgetline(&line[2], sizeof(line)-3, &i) != FIOSUC) {
ffclose();
(void)unlink(DIRFILE);
ewprintf("No such directory: `%s'", dirname);
return NULL;
}
while (ffgetline(&line[2], sizeof(line)-3, &i) == FIOSUC) {
line[i+2] = '\0';
(VOID) addline(bp, line);
}
ffclose();
(void)unlink(DIRFILE);
bp->b_dotp = lforw(bp->b_linep); /* go to first line */
(VOID) strncpy(bp->b_fname, dirname, NFILEN);
if((bp->b_modes[0] = name_mode("dired")) == NULL) {
bp->b_modes[0] = &map_table[0];
ewprintf("Could not find mode dired");
return NULL;
}
bp->b_nmodes = 0;
return bp;
}
/* this is really ugly, but then so was the UNIX version! */
#define BASENAME 2
#define EXT 11
#define DIR 15
d_makename(lp, fn)
register LINE *lp;
register char *fn;
{
register char *cp;
register char *last;
int len;
extern char *strchr();
if(llength(lp) != 41) return ABORT;
if(lgetc(lp,BASENAME) == ' ') return ABORT;
if(lgetc(lp,EXT-1) != ' ') return ABORT;
(VOID) strcpy(fn, curbp->b_fname);
cp = fn + strlen(fn);
if ((cp[-1] != '\\') && (cp[-1] != '/')) /* append '/' if needed */
*cp++ = '\\';
if ((last = strchr(lp->l_text+BASENAME, ' ')) == 0) return ABORT;
len = last - (lp->l_text+BASENAME);
bcopy(lp->l_text+BASENAME, cp, len);
cp += len;
if ((last = strchr(lp->l_text+EXT, ' ')) == 0) return ABORT;
len = last - (lp->l_text+EXT);
if (len != 0) {
*cp++ = '.';
bcopy(lp->l_text+EXT, cp, len);
}
cp[len] = '\0';
return (strncmp(lp->l_text+DIR, "<DIR>", 5) == 0);
}
/* sorry, this is a hack - jpn */
/* I should probably fix this */
copy(frname, toname)
char *frname, *toname;
{
char buffer[512];
int pid;
int status;
char cmdbuf[80];
sprintf(cmdbuf, "Copy %s %s", frname, toname);
system(cmdbuf);
return TRUE;
}
unlinkdir(f)
char *f;
{
return (rmdir(f));
}
#endif /* NO_DIRED */